package com.ruoyi.vote.common.converter;

import com.ruoyi.common.core.page.TableDataInfo;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

public class TableDataInfoConverter {

    public static <T, R> TableDataInfo<R> convert(TableDataInfo<T> source, Class<R> targetClass) {
        List<R> targetDataList = new ArrayList<>();

        for (T sourceData : source.getRows()) {
            R targetData = createTargetInstance(sourceData, targetClass);
            copyFields(sourceData, targetData);
            targetDataList.add(targetData);
        }

        TableDataInfo<R> target = new TableDataInfo<>();
        target.setTotal(source.getTotal());
        target.setRows(targetDataList);
        return target;
    }

    private static <T, R> R createTargetInstance(T sourceData, Class<R> targetClass) {
        try {
            return targetClass.getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            throw new RuntimeException("创建目标实例失败", e);
        }
    }

    private static <T, R> void copyFields(T sourceData, R targetData) {
        Field[] sourceFields = sourceData.getClass().getDeclaredFields();
        Field[] targetFields = targetData.getClass().getDeclaredFields();

        for (Field sourceField : sourceFields) {
            try {
                Field targetField = findTargetField(sourceField.getName(), targetFields);
                if (targetField != null) {
                    sourceField.setAccessible(true);
                    targetField.setAccessible(true);
                    targetField.set(targetData, sourceField.get(sourceData));
                }
            } catch (Exception e) {
                throw new RuntimeException("复制字段失败", e);
            }
        }
    }

    private static Field findTargetField(String fieldName, Field[] targetFields) {
        for (Field targetField : targetFields) {
            if (targetField.getName().equals(fieldName)) {
                return targetField;
            }
        }
        return null;
    }
}
